#include "infinity.h"

const int MAX_PIECES = 8;
const int BOARD_X = 6;
const int BOARD_Y = 6;
const int POINTER_Y = 10;

color board[4][4] = {
  { EMPTY, EMPTY, EMPTY, EMPTY },
  { EMPTY, EMPTY, EMPTY, EMPTY },
  { EMPTY, EMPTY, EMPTY, EMPTY },
  { EMPTY, EMPTY, EMPTY, EMPTY }
};

Player::~Player(void) {}
Player::Player(void) {}
Player::Player(color _mainColor, color _wildColor) {
    mainColor = _mainColor;
    wildColor = _wildColor;
    pieces = MAX_PIECES;
    usedWild = false;
}
color Player::getMainColor(void)  { return mainColor; }
color Player::getWildColor(void)  { return wildColor; }
int Player::getPieceCount(void)   { return pieces; }
bool Player::isWildUse(void)      { return usedWild; }
void Player::useWild(void)        { usedWild = true; }
void Player::returnWild(void)     { usedWild = false; }
void Player::incrementPiece(void) { pieces++; }
void Player::decrementPiece(void) { pieces--; }

Infinity::~Infinity(void) {}
Infinity::Infinity(void) {}
char Infinity::colorChar(color _color) {
    switch(_color) {
        case BLUE:   return 'U';
        case BLACK:  return 'A';
        case YELLOW: return 'Y';
        case WHITE:  return 'W';
        default:     return 'X';
    }
}
void Infinity::drawBoard() {
    int x = BOARD_X;
    int y = BOARD_Y;
    for (int i=0; i<4; i++) {
        printf("\x1b[%i;%iH",y+i,x);
        for (int j=0; j<4; j++) {
            color currentColor = board[i][j];
            char print = colorChar(currentColor);
            printf("%c",print);
        }
    }
}
void Infinity::eraseBoard(void) {
    int x = BOARD_X;
    int y = BOARD_Y;
    for (int i=0; i<5; i++) {
        printf("\x1b[%i;%iH    ",(y+i),x);
        for (int j=0; i<4 && j<4; j++) {
            board[i][j] = EMPTY;
        }
    }
    iprintf("\x1b[2;2H        ");
    iprintf("\x1b[1;1H ");
    iprintf("\x1b[10;10H ");

}
color Infinity::addPiece( int place, color pieceColor) {
    color gutter = board[0][place];
    for (int i=0;i<3;i++)
        board[i][place] = board[i+1][place];
    board[3][place] = pieceColor;
    return gutter;
}
void Infinity::checkScore(Player **player, int *score) {
    int playerScores[2] = { 0, 0 };
    for (int ii=0; ii<2; ii++ ) {
        for (int jj=0; jj<4; jj++) {
            bool scoring = true;
            for (int kk=0; kk<3 && score; kk++)
                scoring = (board[jj][kk] == player[ii]->getMainColor() || board[jj][kk] == player[ii]->getWildColor());
            if (scoring) playerScores[ii]++;
        }
    }
    score++;//j.f.t.f.o.i.
}
int Infinity::run(void) {

  int *score = 0;

  Player *player[2] = {
      new Player(   BLUE, BLACK ),
      new Player( YELLOW, WHITE )
  };

    //this is bs ftfoi
    checkScore(player,score);
    //

  int playersTurn = 0;
  int pointer = 0;
  bool paused = false;
  bool change = true;
  color use = EMPTY;
  color gutter = EMPTY;

  printf("\x1b[2;2HInfinity");
  printf("\x1b[%i;%iH^",POINTER_Y,BOARD_X);

  while(1) {

    iprintf("\x1b[1;1H%i",playersTurn);

    WPAD_ScanPads();

    u32 b_down = WPAD_ButtonsDown(0);//playersTurn);
    u32 b_held = WPAD_ButtonsHeld(0);//playersTurn);

    if (paused) {
      if ( b_down & WPAD_BUTTON_PLUS ) {
          paused = false;
          printf("\x1b[4;4H      ");
      }
    }
    else {
      if ( change ) {
          gutter = addPiece( pointer, use );
          drawBoard();
          for (int i=0; i<2; i++) {
              if (player[i]->getMainColor() == gutter){
                player[i]->incrementPiece();
                break;
              }
              if (player[i]->getWildColor() == gutter){
                player[i]->returnWild();
                break;
              }
          }
          gutter = EMPTY;
          use = EMPTY;
          change = false;
      }
      else {
          if ( b_down & WPAD_BUTTON_HOME ) {
            eraseBoard();
            return 0;
          }
          if ( b_down & WPAD_BUTTON_PLUS ) {
            printf("\x1b[4;4HPAUSED");
            paused = true;
          }

          if ( b_down & WPAD_BUTTON_LEFT ) {
            printf("\x1b[%i;%iH ",POINTER_Y,(BOARD_X + pointer));
            pointer = (--pointer < 0)?3:pointer;
            printf("\x1b[%i;%iH^",POINTER_Y,(BOARD_X + pointer));
          }
          if ( b_down & WPAD_BUTTON_RIGHT ) {
            printf("\x1b[%i;%iH ",POINTER_Y,(BOARD_X + pointer));
            ++pointer %= 4;
            printf("\x1b[%i;%iH^",POINTER_Y,(BOARD_X + pointer));
          }

          if ( b_held & WPAD_BUTTON_B ) {
              if ( ! player[playersTurn]->isWildUse() ) {
                  printf("\x1b[10;10H%c",colorChar( player[playersTurn]->getWildColor()) );
                  if ( b_down & WPAD_BUTTON_A ) {
                      use = player[playersTurn]->getWildColor();
                      player[playersTurn]->useWild();
                      change = true;
                  }
              }
              else
                  printf("\x1b[10;10HX");
          }
          else {
              if ( player[playersTurn]->getPieceCount() > 0 ) {
                  printf("\x1b[10;10H%c", colorChar( player[playersTurn]->getMainColor()) );
                  if ( b_down & WPAD_BUTTON_A ) {
                    use = player[playersTurn]->getMainColor();
                    player[playersTurn]->decrementPiece();
                    change = true;
                  }
              }
              else if ( player[playersTurn]->isWildUse() ) {
                  playersTurn++;
                  playersTurn %= 2;
              }
              else {
                  printf("\x1b[10;10HX");
              }
          }
       }
       if ( change ) {
          playersTurn++;
          playersTurn %= 2;
       }
    }
    VIDEO_WaitVSync();
  }

  return 0;
}
